/* Copyright (c) 2025 Huawei Technologies Co., Ltd.
 * openUBMC is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */

#ifndef __SPDM_COMMAND_IMPL_H__
#define __SPDM_COMMAND_IMPL_H__

#include "common.h"

extern "C" {
#include "hal/base.h"
#include "internal/libspdm_common_lib.h"
#include "internal/libspdm_requester_lib.h"
}

#ifdef G_ENABLE_TEST
const static string test_cert_str = R"(
-----BEGIN CERTIFICATE-----
MIIFhzCCA2+gAwIBAgIUbH8N/x+U/MISQ5QAtYHFmp53dOEwDQYJKoZIhvcNAQEL
BQAwUjELMAkGA1UEBhMCQ04xCzAJBgNVBAgMAlNDMQswCQYDVQQHDAJDRDELMAkG
A1UECgwCSFcxCzAJBgNVBAsMAklUMQ8wDQYDVQQDDAZUZXN0Q0EwIBcNMjUxMTIw
MDIzNTU1WhgPMjA3NTExMDgwMjM1NTVaMFIxCzAJBgNVBAYTAkNOMQswCQYDVQQI
DAJTQzELMAkGA1UEBwwCQ0QxCzAJBgNVBAoMAkhXMQswCQYDVQQLDAJJVDEPMA0G
A1UEAwwGVGVzdENBMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA2LtT
e9C6FFn0QGiM0NehL0lnRjgwcUr1Kzt1vbofILD5rFXqEoHuM5BnhJOA2U0X/BPp
4SVkWm47p5kroEMF2d0+srw6lgW9VgQ6vyg1qpb+0kGSnvVa3ygVym7e0aB0ZGTs
6UrvaMBirh9K94KZSRGb24+1pFYe2xWovj77CjXW/IuGYrJpL81bOQei8d57FkDE
2CjAbILsYGygfH8mzzNg0pW0a/pmqXcyRmosoPSl8dVVpIcSKxiImb9lf8lzYC/1
W1K8cgIpg1nCAGVcM+8jUTQYHDLNRFSXesXuKfVqf/QNTwRuKvtHFcRKPlwYQN9R
COYZFKWIOBcEtAT2iiZHE4K8w80Q43LYuoatTfNiAWdJo3PQ8E3he1fTTfSvns2s
4U6zJcyQyJRuL4MMGF8hWpCFaJwH9JbqnU+YMzPa0tArdDw8Jisn4N0P/PI1+Uyn
HrRJ7gOgoDrV6kfTpIzRNT8HuUyEtDrlFSJYhPh/7g3AJzx4yfLXgaJS0ko6pH5Z
Ae107XfMCAaB8diKqR2CzVI3MJkNMB+csfL9gY7xJCSICHgMjcyYDPHFRX0b3BZ6
GkTEL6nRoYcuTjoMZVQQui7wt5MkP/bAV+jfeUK/3WUcOORD3mJU8fGODwHhIHvh
Ig/Mjz9DG8JhY71IskjDwBzKdPhLE3JFxm51gVMCAwEAAaNTMFEwHQYDVR0OBBYE
FNGhRTiX+BAhKY/ZfEZ9PGDXx28KMB8GA1UdIwQYMBaAFNGhRTiX+BAhKY/ZfEZ9
PGDXx28KMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggIBAHOR/akw
mvjupAnr0hpbTNBtUmLI6Xgo+LMUA4zRYpGGSyv5ITXHN40/UevS9/QYzOCiIf9y
XSHgfQlUuwVL1CbZjsHk+BJngY/4+VxWglXEfgBMs/7x4Dv67u7mW89Xdyc3cdEP
qXroay2xdcbZMvV5Q4ovWA+8VyecaL6iTsYzhL9786mibPzlEMteaxLevyoPa77u
ElJZl5ki6MdKTmAPCnQf9pFbZbHCmUIAjGqmoPR7vNELjsfdUaIA0riDGzIfBXSZ
rU4k5APC6oZwGaLp+I3UoGRWI7BCMeAFJdCSO8YALhW5rXPWmFYizqB9V7624AiQ
eLyZBWegsAfJGgtwTd4kq6Yom1YYo+dGX4CFbJ0lDADhYS0nndktvrcGvpt5tvx/
9kNUJ8Fja9lWZXbAPZIUBBP+QNTqyRlVnUaYdUPvGwwb6aLGCjdRhxQMmMGckesA
ZQY+7qc5WyYTDktMJ6xIIEcUc9zp46TkZiIkLnsFoo5H3DLKk3bblNKk2/wEfV74
CUgvECATtHCHI4LYxUiZ4VnDkW/hvQjbNe18zbPpk8hvBHVCwMB7ioXSYg9IWXdc
LqSeEZ2PvXQ3o31NCnEhtXIAXgrPsvTsn/6DjbWAfvBDSzRGlybqr2/bIDd0pbiu
4UQ5ABezaxPusctFxSt1d+CtUKot9k+4hBz8
-----END CERTIFICATE-----)";

#define DEFAULT_HASH_SIZE 32
const static array<uint8_t, DEFAULT_HASH_SIZE> g_mock_measurement_1 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00};
const static array<uint8_t, DEFAULT_HASH_SIZE> g_mock_measurement_2 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x01};
const static array<uint8_t, DEFAULT_HASH_SIZE> g_mock_measurement_3 = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
    0x00, 0x00, 0x00, 0x00, 0x02};
const static map<uint8_t, array<uint8_t, DEFAULT_HASH_SIZE>> g_measurements = {
    {1, g_mock_measurement_1},
    {2, g_mock_measurement_2},
    {3, g_mock_measurement_3}
};

const static uint8_t g_all_measurement[DEFAULT_HASH_SIZE] = {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x01, 0x01, 0x01};
#endif // G_ENABLE_TEST

// =================================================== SPDM公共函数 ===================================================
bool CheckContext(void *spdm_context);
size_t GetContextSize(void);
size_t GetContextSizeWithoutSecuredContext(void);
uint32_t InitContext(void *spdm_context);

void RegisterDeviceIoFunc(void *spdm_context, libspdm_device_send_message_func send_message,
    libspdm_device_receive_message_func receive_message);
void RegisterTransportLayerFunc(
    void *spdm_context,
    uint32_t max_spdm_msg_size,
    uint32_t transport_header_size,
    uint32_t transport_tail_size,
    libspdm_transport_encode_message_func transport_encode_message,
    libspdm_transport_decode_message_func transport_decode_message);
void RegisterDeviceBufferFunc(
    void *spdm_context,
    uint32_t sender_buffer_size,
    uint32_t receiver_buffer_size,
    libspdm_device_acquire_sender_buffer_func acquire_sender_buffer,
    libspdm_device_release_sender_buffer_func release_sender_buffer,
    libspdm_device_acquire_receiver_buffer_func acquire_receiver_buffer,
    libspdm_device_release_receiver_buffer_func release_receiver_buffer);
uint32_t SpdmSetData(void *spdm_context, libspdm_data_type_t data_type, const libspdm_data_parameter_t *parameter,
    const void *data, size_t data_size);
uint32_t SpdmGetData(void *spdm_context, libspdm_data_type_t data_type, const libspdm_data_parameter_t *parameter,
    void *data, size_t *data_size);
void ZeroMem(void *buffer, size_t length);
size_t GetRequiredScratchBufferSize(void *spdm_context);
void SetScratchBuffer(void *spdm_context, void *scratch_buffer, size_t scratch_buffer_size);

size_t GetHashSize(uint32_t base_hash_algo);
// =================================================== SPDM请求端函数 ===================================================
uint32_t InitSpdmConnection(void *spdm_context, bool get_version_only);
uint32_t GetDigest(void *spdm_context, const uint32_t *session_id, uint8_t *slot_mask, void *total_digest_buffer);
uint32_t GetCertificate(void *spdm_context, const uint32_t *session_id, uint8_t slot_id, size_t *cert_chain_size,
    void *cert_chain);
uint32_t ChallengeAuth(void *spdm_context, void *reserved, uint8_t slot_id, uint8_t measurement_hash_type,
    void *measurement_hash, uint8_t *slot_mask);
uint32_t GetMeasurement(void *spdm_context, const uint32_t *session_id, uint8_t request_attribute,
    uint8_t measurement_operation, uint8_t slot_id, uint8_t *content_changed, uint8_t *number_of_blocks,
    uint32_t *measurement_record_length, void *measurement_record);
uint32_t GetMeasurementEx(void *spdm_context, const uint32_t *session_id,
    uint8_t request_attribute,
    uint8_t measurement_operation,
    uint8_t slot_id,
    uint8_t *content_changed,
    uint8_t *number_of_blocks,
    uint32_t *measurement_record_length,
    void *measurement_record,
    const void *requester_nonce_in,
    void *requester_nonce,
    void *responder_nonce,
    void *opaque_data,
    size_t *opaque_data_size);

#endif // __SPDM_COMMAND_IMPL_H__